#ifndef _STASH_H_
#define _STASH_H_
#include "../Scheduler/OperationInfo.h"
/*This class simulates non-volatile store*/
class Stash{

public:

 /*TODO:Wire this up to talk to the PowerModels
  Ideally we should be able to say NVWrite/NVRead()
  to the PowerModel and it should automatically
  deduct the correct amount of energy.  Maybe this
  happens via the Scheduler.
  */

  /*TODO: Wire this up to the Scheduler to
  cost the right number of cycles when performing
  one of these operations.  It will be an additional
  operation type (like Read, Write, or Ins).*/

  /*These numbers assume PCM as the non-volatile
    memory technology.  Taken from Table 1, col 3 in
    Rethinking Database Algorithms for Phase Change Memory
    Chen, Gibbons, Nath, CIDR 2011 
  static const unsigned long idlePower = 1; //pW / B
  static const unsigned long writeEnergy = 6; //nJ / B
  static const unsigned long readEnergy = 1; //nJ / B
  static const unsigned long readLatency = 50; //ns
  static const unsigned long writeLatency = 1000; //ns
  */ 
 
  /*These numbers assume FRAM as the non-volatile
    memory technology.  Taken from the MSP430FR59xx datasheet
    And here: http://www.digikey.com/classic/documentredirector.aspx?doc=http://www.digikey.com%2fWeb%20Export%2fSupplier%20Content%2framtron-1140%2fpdf%2framtron-tech-fram-eeprom-comparison.pdf&curr=USD

    and here!

    http://www.digikey.com/classic/documentredirector.aspx?doc=http://www.digikey.com%2fWeb%20Export%2fSupplier%20Content%2framtron-1140%2fpdf%2framtron-tech-ferroelectric.pdf&curr=USD

  6nJ / 64ns = 0.09W access power 
  */

  OperationInfo *info;

  static const unsigned long writeEnergy = 6; //nJ / B
  static const unsigned long readEnergy = 6; //nJ / B
  static const unsigned long readLatency = 5; //ns / B -- uses mem caching
  static const unsigned long writeLatency = 64; //ns / B

  Stash(size_t size);

  unsigned long stashSize; //bytes of NV store
  char *stash; //the bytes that store the stash

  /*size is in Bytes*/
  OperationInfo *store(void *value, unsigned long NVAddr, size_t size);
  OperationInfo *load(void *buf, unsigned long NVAddr, size_t size); 
  
  /*size is in Bytes*/
  OperationInfo *nonResidentStore( size_t size );
  OperationInfo *nonResidentLoad( size_t size ); 

};
#endif
